package org.metasketch.diagram.javafx.graphics;

import java.util.List;

import javafx.scene.transform.Rotate;

import org.metasketch.editor.links.LineSection;
import org.metasketch.graphics.Point2f;

public class PositionedLabel {

	CustomLabel label = new CustomLabel();

	VerticalLinkLabelPosition vertical = VerticalLinkLabelPosition.CENTER;

	HorizontalLinkLabelPosition horizontal = HorizontalLinkLabelPosition.CENTER;

	public void positionLabel(BaseLink link, List<LineSection> lines) {

		setHorizontalPosition(link, lines);

		setVerticalPosition(link, lines);

	}

	private void setHorizontalPosition(BaseLink link, List<LineSection> lines) {
		if (horizontal == HorizontalLinkLabelPosition.CENTER) {
			int rest = lines.size() % 2;
			if (rest == 0) {
				// get the middle control point
				int index = lines.size() / 2 - 1;
				LineSection line = lines.get(index);
				int x = (int) line.getEndX();

				x -= label.getWidth() / 2;

				label.setTranslateX(x);

			} else {
				int index = lines.size() / 2;
				LineSection line = lines.get(index);

				int x = (int) (line.getStartX() + (line.getEndX() - line
						.getStartX()) * 0.5);

				x -= label.getWidth() / 2;

				label.setTranslateX(x);
			}
		} else if (horizontal == HorizontalLinkLabelPosition.SOURCE) {

			if (link.getFirstSection().getSource() == link.getSource()) {

				LineSection section = link.getFirstSection();

				setNewPosition((int) section.getStartX(),
						(int) section.getStartY(), (int) section.getEndX(),
						(int) section.getEndY());

				// int x = (int) link.getFirstSection().getStartX();
				//
				// label.setTranslateX(x);

			} else if (link.getLastSection().getTarget() == link.getSource()) {

				LineSection section = link.getLastSection();

				setNewPosition((int) section.getEndX(),
						(int) section.getEndY(), (int) section.getStartX(),
						(int) section.getStartY());

				// int x = (int) link.getFirstSection().getEndX();
				//
				// label.setTranslateX(x);

			}

		} else if (horizontal == HorizontalLinkLabelPosition.TARGET) {

			if (link.getFirstSection().getSource() == link.getTarget()) {

				LineSection section = link.getFirstSection();

				setNewPosition((int) section.getStartX(),
						(int) section.getStartY(), (int) section.getEndX(),
						(int) section.getEndY());

				// int x = (int) link.getFirstSection().getStartX();
				//
				// label.setTranslateX(x);

			} else if (link.getLastSection().getTarget() == link.getTarget()) {

				LineSection section = link.getLastSection();

				setNewPosition((int) section.getEndX(),
						(int) section.getEndY(), (int) section.getStartX(),
						(int) section.getStartY());

				// int x = (int) link.getFirstSection().getEndX();
				//
				// label.setTranslateX(x);
			}

		}

	}

	private void setVerticalPosition(BaseLink link, List<LineSection> lines) {
		if (horizontal == HorizontalLinkLabelPosition.CENTER) {
			if (vertical == VerticalLinkLabelPosition.CENTER) {
				int rest = lines.size() % 2;
				if (rest == 0) {
					// get the middle control point
					int index = lines.size() / 2 - 1;
					LineSection line = lines.get(index);
					int y = (int) line.getEndY();

					y -= label.getHeight();

					label.setTranslateY(y);

				} else {
					int index = lines.size() / 2;
					LineSection line = lines.get(index);

					int y = (int) (line.getStartY() + (line.getEndY() - line
							.getStartY()) * 0.5);

					y -= label.getHeight();

					label.setTranslateY(y);
				}
			} else if (vertical == VerticalLinkLabelPosition.TOP) {
				int rest = lines.size() % 2;
				if (rest == 0) {
					// get the middle control point
					int index = lines.size() / 2 - 1;
					LineSection line = lines.get(index);
					int y = (int) line.getEndY();

					y -= 20;

					label.setTranslateY(y);

				} else {
					int index = lines.size() / 2;
					LineSection line = lines.get(index);

					int y = (int) (line.getStartY() + (line.getEndY() - line
							.getStartY()) * 0.5);

					y -= 20;

					label.setTranslateY(y);
				}
			} else if (vertical == VerticalLinkLabelPosition.BOTTOM) {
				int rest = lines.size() % 2;
				if (rest == 0) {
					// get the middle control point
					int index = lines.size() / 2 - 1;
					LineSection line = lines.get(index);
					int y = (int) line.getEndY();

					// y += 10;

					label.setTranslateY(y);

				} else {
					int index = lines.size() / 2;
					LineSection line = lines.get(index);

					int y = (int) (line.getStartY() + (line.getEndY() - line
							.getStartY()) * 0.5);

					// y += 10;

					label.setTranslateY(y);
				}
			}
		} else {

			if (vertical == VerticalLinkLabelPosition.TOP) {

				label.setTranslateY(label.getTranslateY() - 10);
			} else if (vertical == VerticalLinkLabelPosition.BOTTOM) {

				label.setTranslateY(label.getTranslateY() + 10);
			}
		}

	}

	public void setNewPosition(int x, int y, int sectionX, int sectionY) {
		double angle = getAngleInDegrees(x, y, sectionX, sectionY);
		// doRotation(angle);

		// angle+=180;

		// angle = angle + 90;

		// System.out.println(angle);

		// double rightAngle = angle;
		// Point2f translateVector = getVectorFromAngle(rightAngle);
		// double tan = Math.cos(Math.toRadians(rightAngle * 0.5));

		// double scale = tan * label.getWidth();

		// translateVector.scale(50.0);
		// if (x > sectionX)
		// translateVector.scale(scale);
		// else
		// translateVector.scale(-scale);

		// label.setTranslateX(x);
		// label.setTranslateY(y);

		int radius = 40;

		label.setTranslateX(x + radius * Math.cos(Math.toRadians(angle))
				- radius);
		label.setTranslateY(y - (radius * Math.sin(Math.toRadians(angle)))
				* 0.4 - 10);

		System.out.println(angle + " -> x: " + x + ", y:" + y + " -> "
				+ label.getTranslateX() + ", " + label.getTranslateY() + " W:"
				+ label.getWidth() + " H:" + label.getHeight());

		// if (label.getTranslateX() + label.getWidth() > x) {
		// label.setTranslateX(label.getTranslateX() - label.getWidth());
		// }
		//
		// if (label.getTranslateY() + label.getHeight() > y) {
		// label.setTranslateY(label.getTranslateY() - label.getHeight());
		// }

		// setTranslateX(x);
		// setTranslateY(y);
	}

	private Point2f getVectorFromAngle(double rightAngle) {

		return new Point2f(Math.cos(Math.toRadians(rightAngle)), Math.sin(Math
				.toRadians(rightAngle)));
	}

	protected Point2f getUnitVector(int x, int y, int sectionX, int sectionY) {
		int dx = x - sectionX;
		int dy = y - sectionY;

		double magV = Math.sqrt(dx * dx + dy * dy);
		double aX = dx / magV;
		double aY = dy / magV;

		return new Point2f(aX, aY);
	}

	protected Point2f getUnitVector(int x, int y, int sectionX, int sectionY,
			double size) {
		int dx = x - sectionX;
		int dy = y - sectionY;

		double magV = Math.sqrt(dx * dx + dy * dy);
		double aX = x - dx / magV * size;
		double aY = y - dy / magV * size;

		return new Point2f(aX, aY);
	}

	protected double getAngleInDegrees(int x, int y, int sectionX, int sectionY) {
		int dx = x - sectionX;
		int dy = y - sectionY;

		return getAngleInDegrees(dx, dy);

	}

	protected double getAngleInDegrees(int vx, int vy) {
		double a = Math.atan2(vx, vy);
		if (a < 0) {
			a += Math.PI * 2.0;
		}
		return Math.toDegrees(a) - 270.0;
	}

	public CustomLabel getLabel() {
		return label;
	}

	public void setLabel(CustomLabel label) {
		this.label = label;
	}

	public VerticalLinkLabelPosition getVertical() {
		return vertical;
	}

	public void setVertical(VerticalLinkLabelPosition vertical) {
		this.vertical = vertical;
	}

	public HorizontalLinkLabelPosition getHorizontal() {
		return horizontal;
	}

	public void setHorizontal(HorizontalLinkLabelPosition horizontal) {
		this.horizontal = horizontal;
	}

}
